package com.hxkj.service.impl;


import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hxkj.dao.*;
import com.hxkj.domain.enums.AuthRoleExceptionEnum;
import com.hxkj.domain.po.*;
import com.hxkj.service.AuthRoleService;
import com.hxkj.utils.StrSliptUtils;
import com.platform.common.domain.result.ResultDataStruct;
import com.platform.common.domain.result.ResultMessageStruct;
import com.platform.common.domain.to.PageTo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户mapper
 * <p>
 * Created by chengfangzhou on 2018/5/15.
 */
@Service
@Slf4j
public class AuthRoleServiceImpl implements AuthRoleService {


    @Autowired
    private AuthRoleDao authRoleDao;
    @Autowired
    private AuthFunctionDao authFunctionDao;

    @Autowired
    private AuthRoleFunctionDao authRoleFunctionDao;

    @Autowired
    private AuthUserRoleAppDao authUserRoleAppDao;
    @Autowired
    private FunctionDao functionDao;

    /**
     * 保存角色
     *
     * @param authRole
     * @return
     * @throws Exception
     */
    @Override
    public ResultMessageStruct saveAuthRole(AuthRole authRole) throws Exception {
        ResultMessageStruct resultMessageStruct = new ResultMessageStruct();
        // 根据角色名判断是否重复添加
        AuthRole role = new AuthRole();
        role.setRoleName(authRole.getRoleName());
        role.setSiteId(authRole.getSiteId());
        role.setDelTag((byte) 0);
        if (authRoleDao.getRoleList(role).size() > 0) {
            resultMessageStruct.setCode(AuthRoleExceptionEnum.AUTHROLE_EXIST_ALREADY.getCode());
        } else {
            authRole.setCreateTime(System.currentTimeMillis());
            authRole.setUpdateTime(System.currentTimeMillis());
            int i = authRoleDao.save(authRole);
            resultMessageStruct.setCode(200);
        }
        return resultMessageStruct;
    }

    /**
     * 获取单个角色
     *
     * @param authRole
     * @return
     * @throws Exception
     */
    @Override
    public ResultDataStruct<AuthRole> getAuthRole(AuthRole authRole) throws Exception {

        ResultDataStruct<AuthRole> resultDataStruct = new ResultDataStruct<>();
        try {
            AuthRole role = authRoleDao.get(authRole.getRoleId());

            if (role == null) {
                resultDataStruct.setCode(AuthRoleExceptionEnum.ROLE_IS_NULL.getCode());
                return resultDataStruct;
            } else {
                if (role.getDelTag() == (byte) 1) {
                    resultDataStruct.setCode(AuthRoleExceptionEnum.ROLE_IS_NULL.getCode());
                    return resultDataStruct;
                } else {
                    resultDataStruct.setCode(200);
                    resultDataStruct.setData(role);
                    return resultDataStruct;
                }
            }
        } catch (Exception e) {
            resultDataStruct.setCode(AuthRoleExceptionEnum.AUTHROLE_QUERY_ERROR.getCode());
            e.printStackTrace();
            return resultDataStruct;
        }
    }


    /**
     * 获取角色列表,带分页
     *
     * @param authRole
     * @param pageParam
     * @return
     * @throws Exception
     */
    @Override
    public PageInfo<AuthRole> getRoleList(AuthRole authRole, PageTo pageParam) throws Exception {
        try {
            if (pageParam.getPageNum() == null || pageParam.getPageSize() == null) {
                pageParam.setPageNum(1);
                pageParam.setPageSize(10);
            }
            authRole.setDelTag((byte) 0);
            Page<AuthRole> page = PageHelper.startPage(pageParam.getPageNum(), pageParam.getPageSize());
            authRoleDao.getRoleList(authRole);
            PageInfo<AuthRole> pageInfo = new PageInfo<>(page);
            return pageInfo;
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }


    /**
     * 查找从数据库
     *
     * @param authRole
     * @param pageParam
     * @return
     * @throws Exception
     */
    @Override
    public PageInfo<AuthRole> getAuthRoleBySlave(AuthRole authRole, PageTo pageParam) throws Exception {
        try {
            if (pageParam.getPageNum() == null || pageParam.getPageSize() == null) {
                pageParam.setPageNum(1);
                pageParam.setSize(10);
            }
            Page<AuthRole> page = PageHelper.startPage(pageParam.getPageNum(), pageParam.getSize());
            authRole.setDelTag((byte) 0);
            PageInfo<AuthRole> pageInfo = null;

            List<AuthRole> roleListList = authRoleDao.getBySlave(authRole);
            pageInfo = new PageInfo<>(page);
            pageInfo.setList(roleListList);
            return pageInfo;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }


    @Override
    public AuthRole getAuthRoleFromCache(Long roleId) throws Exception {
        AuthRole authRole = new AuthRole();
        authRole.setRoleId(roleId);
        log.info("没有命中缓存");
        return authRole;
    }

    @Override
    public ResultMessageStruct updateAuthRole(AuthRole authRole) {
        ResultMessageStruct result = new ResultMessageStruct();
        try {
            if (authRole.getRoleName() == null) {
                result.setCode(AuthRoleExceptionEnum.ROLENAME_IS_NULL.getCode());
                return result;
            }
            // 根据角色名称判断是否有重复
            AuthRole authRoleName = authRoleDao.selectRoleName(authRole);
            if (authRoleName != null) {
                result.setCode(AuthRoleExceptionEnum.AUTHROLE_EXIST_ALREADY.getCode());
                return result;
            }
            // 如果角色跟用户或功能有关联,不允许禁用
            if (authRole.getRoleStatus() != null && authRole.getRoleStatus() == 1) {
                if (!validateDelete(authRole.getRoleId())) {
                    result.setCode(AuthRoleExceptionEnum.ROLE_HAS_USER_OR_FUNCTION.getCode());
                    return result;
                }
            }
            int i = authRoleDao.update(authRole);
            result.setCode(i > 0 ? 200 : AuthRoleExceptionEnum.AUTHROLE_UPDATE_ERROR.getCode());
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            result.setCode(AuthRoleExceptionEnum.AUTHROLE_UPDATE_ERROR.getCode());
            return result;
        }
    }

    /**
     * 删除角色,可批量删除,也可单条删除
     *
     * @param authRole
     * @return
     */
    @Override
    public ResultMessageStruct deleteAuthRole(AuthRole authRole) {
        ResultMessageStruct resultMessageStruct = new ResultDataStruct<>();
        try {
            // 删除多条
            if (authRole.getRoleIds() != null && authRole.getRoleIds() != "") {
                String[] str = StrSliptUtils.sliptArray(authRole.getRoleIds());
                for (int i = 0; i < str.length; i++) {
                    // 超级管理员角色不能删除
                    if ("1".equals(str[i])) {
                        resultMessageStruct.setCode(AuthRoleExceptionEnum.ADMIN_ANNNOT_DELETE.getCode());
                        return resultMessageStruct;
                    }
                    //改为硬删除,判断该角色是否关联用户和功能
                    if (validateDelete(Long.valueOf(str[i]))) {
                        authRoleDao.delete(Long.valueOf(str[i]));
                    } else {
                        //抛出异常
                        resultMessageStruct.setCode(AuthRoleExceptionEnum.ROLE_HAS_USER_OR_FUNCTION.getCode());
                        return resultMessageStruct;
                    }
                }
            } else {// 删除单条
                if (validateDelete(authRole.getRoleId())) {
                    authRoleDao.delete(authRole.getRoleId());
                } else {
                    resultMessageStruct.setCode(AuthRoleExceptionEnum.ROLE_HAS_USER_OR_FUNCTION.getCode());
                    return resultMessageStruct;
                }

            }
            resultMessageStruct.setCode(200);
            return resultMessageStruct;
        } catch (NumberFormatException e) {
            e.printStackTrace();
            resultMessageStruct.setCode(AuthRoleExceptionEnum.AUTHROLE_DELETE_ERROR.getCode());
            return resultMessageStruct;
        }
    }

    /**
     * 删除角色前,判断该角色下是否关联用户或功能(自定义内部方法)
     *
     * @param roleId
     * @return
     * @throws Exception
     */
    private boolean validateDelete(Long roleId) {
        // 判断该角色下是否关联有账号
        AuthUserRoleApp userRole = new AuthUserRoleApp();
        userRole.setRoleId(roleId);
        List<AuthUserRoleApp> authUserRole = authUserRoleAppDao.get(userRole);
        // 判断该角色下是否关联有功能
        AuthRoleFunction roleFunctin = new AuthRoleFunction();
        roleFunctin.setRoleId(roleId);
        List<AuthRoleFunction> authRoleFunctions = authRoleFunctionDao.get(roleFunctin);
        if ((authUserRole == null || authUserRole.size() == 0) && (authRoleFunctions == null || authRoleFunctions.size() == 0)) {
            return true;
        }
        return false;
    }


    /**
     * 刷新缓存
     *
     * @param roleId
     * @return
     * @throws Exception
     */
    @Override
    public AuthRole getAuthRoleRefresh(Long roleId) throws Exception {
        AuthRole authRole = new AuthRole();
        authRole.setRoleId(roleId);
        log.info("缓存刷新");
        return authRole;
    }

    /**
     * 获取功能列表
     *
     * @param authRole 角色
     * @return
     * @throws Exception
     */
    @Override
    public ResultDataStruct<AllocationFunction> getFunction(AuthRole authRole) throws Exception {
        ResultDataStruct<AllocationFunction> result = new ResultDataStruct<>();
        AllocationFunction all = new AllocationFunction();
        List<AuthFunction> allFunction;
        List<AuthFunction> assigned;
        List<Long> functionId;
        //查询该角色已分配得功能
        Map<String, Object> map = new HashMap<>();
        map.put("roleId", authRole.getRoleId());
        map.put("siteId", authRole.getSiteId());
        try {
            assigned = authFunctionDao.getAssigned(map);
            functionId = new ArrayList<>();
            for (AuthFunction function : assigned) {
                functionId.add(function.getFunctionId());
            }
            // 查询所有的功能
            AuthFunction authRo = new AuthFunction();
            authRo.setSiteId(authRole.getSiteId());
            allFunction = authFunctionDao.get(authRo);
        } catch (Exception e) {
            e.printStackTrace();
            result.setCode(AuthRoleExceptionEnum.FIND_ROLE_FUNCTION_ERROR.getCode());
            result.setMessage(AuthRoleExceptionEnum.FIND_ROLE_FUNCTION_ERROR.getMsg());
            return result;
        }

        all.setAllFunction(allFunction);
        all.setAssigned(functionId);
        result.setData(all);
        return result;
    }

    @Override
    public ResultDataStruct getFunctions(AuthRole authRole) throws Exception {
        ResultDataStruct<AllocationFunction> result = new ResultDataStruct<>();
        AllocationFunction all = new AllocationFunction();
        List<FunctionTree> allFunction = new ArrayList<>();
        List<AuthFunction> assigned;
        List<Long> functionId;
        // 查询该角色已分配得功能
        Map<String, Object> map = new HashMap<>();
        map.put("roleId", authRole.getRoleId());
        map.put("siteId", authRole.getSiteId());

        try {
            // 查询角色是否已经被禁用
            AuthRole ro = authRoleDao.get(authRole.getRoleId());
            if (ro.getRoleStatus() != 0) {
                result.setCode(AuthRoleExceptionEnum.ROLE_STATUS_ERROR.getCode());
                result.setMessage(AuthRoleExceptionEnum.ROLE_STATUS_ERROR.getMsg());
                return result;
            }
            // 查询该角色已分配得功能
            assigned = authFunctionDao.getAssigned(map);
            functionId = new ArrayList<>();
            for (AuthFunction function : assigned) {
                functionId.add(function.getFunctionId());
            }
            FunctionTree functionTree = new FunctionTree();
            functionTree.setFunctionId(-1L);
            functionTree.setFunctionName("云平台管理");
            functionTree.setChildren(initTree(-1, authRole));
            allFunction.add(functionTree);
        } catch (Exception e) {
            e.printStackTrace();
            result.setCode(AuthRoleExceptionEnum.FIND_ROLE_FUNCTION_ERROR.getCode());
            result.setMessage(AuthRoleExceptionEnum.FIND_ROLE_FUNCTION_ERROR.getMsg());
            return result;
        }

        all.setAllFunctionTree(allFunction);
        all.setAssigned(functionId);
        result.setData(all);
        return result;
    }

    @Override
    public void saveAllocationFunction(AuthRole authRole) throws Exception {
        String[] functionIdArry = authRole.getFunctionIds().split(",");
        // 清空该角色的所有功能
        authRoleFunctionDao.deleteFunctionByRoleId(authRole.getRoleId());

        if (functionIdArry.length > 0) {
            for (String function : functionIdArry) {
                AuthRoleFunction authRoleFunction = new AuthRoleFunction();
                authRoleFunction.setCreateTime(System.currentTimeMillis());
                authRoleFunction.setRoleId(authRole.getRoleId());
                authRoleFunction.setFunctionId(Long.valueOf(function));
                authRoleFunctionDao.save(authRoleFunction);
            }
        }


    }

    /**
     * 初始化功能数
     *
     * @param id
     * @param authRole
     * @return
     */
    private List<FunctionTree> initTree(long id, AuthRole authRole) {

        List<FunctionTree> functionTrees = new ArrayList<FunctionTree>();
        AuthFunction authFunction = new AuthFunction();
        authFunction.setParentFunctionId(id);
        authFunction.setSiteId(authRole.getSiteId());
        authFunction.setFunctionName("");
        List<AuthFunction> authFunctions = functionDao.getFunctionListByStatus(authFunction);
        if (authFunctions != null && authFunctions.size() != 0) {
            for (AuthFunction auf : authFunctions) {
                FunctionTree functionTree = new FunctionTree();
                functionTree.setFunctionName(auf.getFunctionName());
                functionTree.setFunctionUri(auf.getFunctionUri());
                functionTree.setFunctionId(auf.getFunctionId());
                functionTree.setParentFunctionId(auf.getParentFunctionId());
                functionTree.setFunctionCode(auf.getFunctionCode());
                functionTree.setFunctionStatus(auf.getFunctionStatus());
                functionTree.setFunctionType(auf.getFunctionType());
                functionTree.setFunctionIcon(auf.getFunctionIcon());
                functionTree.setChildren(initTree(auf.getFunctionId(), authRole));
                functionTrees.add(functionTree);
            }
        }
        return functionTrees;
    }
}
